Die mscJNeuralNet-API ist eine pure 100% Java API für vorwärtsgerichtete, mehrschichtige künstliche Neuronale Netze (Multilayered Feedforward-Nets, Multilayered Perceptrons - MLP).
Zusätzlich zu den eigentlichen Netzkomponenten enthält die API auch einige grafische Komponenten zur Steuerung und Darstellung des Netzes.


mscJNeuralNet

Im Zentrum der API stehen folgende Klassen:

  • {@link mscJNeuralNet.net.Net}: Das MLP-Netz. Über diese Klasse kann das Netz selbst abgefragt, geladen, gespeichert oder auch trainiert wird.
  • {@link mscJNeuralNet.trainer.NetTrainer}: Eine Hilfsklasse zum Trainieren eines MLP-Netzes mit mehreren Lerndaten als nebenläufigen Prozess.
  • {@link mscJNeuralNet.connectors.INetConnector}: Die Schnittstelle für verschiedene Verfahren zur Initialisierung der Kantengewichte.
  • {@link mscJNeuralNet.trainingAlgorithms.INetTrainingAlgorithm}: Die Schnittstelle für verschiedene Lernverfahren.
  • {@link mscJNeuralNet.patterns.Patterns}: Die Lerndatenmenge. Über diese Klasse werden Lerndatensätze verwaltet, geladen, gespeichert und kontrolliert.
  • {@link mscJNeuralNet.gui}: Eine Sammlung von Swing-Panels zum Visualisieren und Verwalten der einzelnen Komponenten.
  • Die API setzt an einem sehr generellen Level an und erlaubt daher einfach und schnell MLPs zu erzeugen und einzusetzen. Daraus resultiert aber derzeit auch der Nachteil, dass die Netze nicht beliebige Strukturen und Funktionsweisen haben können. Die API ermöglicht lediglich vollvernetzte, vorwärtsgerichtete Netze mit BIAS und ohne Rekurrenz. Als Transferfunktion steht derzeit nur der Tangens Hyperbolicus (Tanh) zur Verfügung.

    Beispiel für das Trainieren eines MLP mit dem 3-dimensionalen Xor-Problem

    Im folgenden soll ein MLP die dreistellige exklusiv-oder Verknüpfung lernen. Die dreistellige exklusiv-oder Verknüpfung entspricht folgender Tabelle, die im Beispiel als Lerndatensatz benutzt wird:
    Eingaben Ausgabe
    -1-1-1 -1
    -1-11 1
    -11-1 1
    -111 -1
    1-1-1 1
    1-11 -1
    11-1 -1
    111 1

    Das zu trainierende Netz benötigt drei Schichten: Eingabeschicht mit den drei Eingabeneuronen und dem BIAS, verborgene Schicht mit zwei Neuronen und Ausgabeschicht mit einem Neuron.

    Die verborgene Schicht wird hier benötigt, da sonst das linear nicht separable Problem nicht gelernt werden kann.

  • 1. Erzeugen der benötigten Klassen
  • MLP {@link mscJNeuralNet.net.Net}
  • {@link mscJNeuralNet.connectors.INetConnector} für Initialisierung des MLP
  • {@link mscJNeuralNet.trainingAlgorithms.INetTrainingAlgorithm} zum Trainieren des MLP
  • 2. Initialisieren des Netzes
  • MLP + {@link mscJNeuralNet.connectors.INetConnector}
  • 3. Trainieren des Netzes
  • TRAININGSDATEN
  • Lernverfahren mit Netz verbinden
  • 50 TRAININGSZYKLEN
  • Berechnen der aktuellen Netzperformanz (Soll-Ist Fehler)
  • Formatierte Ausgabe der Netzperformanz
  • package mscJNeuralNet.tests;
    
    import mscJNeuralNet.netPerformanceStatistics.NetPerformanceReporter;
    import mscJNeuralNet.connectors.INetConnector;
    import mscJNeuralNet.connectors.RandomSymmetryBreakingNetConnector;
    import mscJNeuralNet.net.Net;
    import mscJNeuralNet.netPerformanceStatistics.NetPerformanceStatistics;
    import mscJNeuralNet.netPerformanceStatistics.NetPerformanceStatisticsCalculator;
    import mscJNeuralNet.net.PatternDoesNotMatchNetException;
    import mscJNeuralNet.trainingAlgorithms.INetTrainingAlgorithm;
    import mscJNeuralNet.trainingAlgorithms.RProp;
    
    // Trainieren eines MLP
    public class TestTrippleXorLearn{
    
      public static void main(String argv[]){
        
        // 1. Erzeugen der benötigten Klassen
        
    		
        
        // MLP {@link mscJNeuralNet.net.Net}
        // MLP mit der gewünschten Schichtstruktur erstellen:
        // Eingabeschicht: 3 Neuronen
        // 1. Verdeckte Schicht: 3 Neuronen
        // Ausgabeschicht: 1 Neuron
        
        int [] layerSizesTrippleXOr = {3, 3, 1};
        
        //* {@link mscJNeuralNet.net.Net} myNet = new Net(layerSizesTrippleXOr);
        
        Net myNet = new Net(layerSizesTrippleXOr);
        
        
        // BIAS wurde automatisch berücksichtigt.
        
    		
        
        // {@link mscJNeuralNet.connectors.INetConnector}
        // Diese Klasse wird zum Initialisieren der Kantengewichte benötigt
        
        INetConnector lNetConnectionAlgo = new RandomSymmetryBreakingNetConnector();
    		
        
        // {@link mscJNeuralNet.trainingAlgorithms.INetTrainingAlgorithm}
        // Diese Klasse wird zum Trainieren eines MLP benötigt
        
        INetTrainingAlgorithm lNetTrainAlgo = new RProp();
    		
        
        // 2. Initialisieren des Netzes
        
    
        
        // MLP + {@link mscJNeuralNet.connectors.INetConnector}
        // Mit der Instanz von {@link mscJNeuralNet.connectors.INetConnector} inititalisieren.
        // Die Klasse {@link mscJNeuralNet.connectors.RandomSymmetryBreakingNetConnector} benötigt
        // keine eigenen Kontrollparameter und wird daher mit dem Wert null aufgerufen.
        
        lNetConnectionAlgo.connectNet(myNet, null);
    		
        
        // Nun ist das Netz verbunden und initialisiert.
        
        
        
        // 3. Trainieren des Netzes
        
        
        
        // TRAININGSDATEN
        // Trainingsdaten bereitstellen
        
        double [][] lTrippleXORtrainInput = {
                    {-1,-1,-1}, {-1,-1,1},
                    {-1,1,-1}, {-1,1,1},
                    {1,-1,-1}, {1,-1,1},
                    {1,1,-1}, {1,1,1}};
        double [][] lTrippleXORtrainOutput = {
                    {-1},{1},
                    {1},{-1},
                    {1}, {-1},
                    {-1}, {1}};
    	
        
        // MLP + {@link mscJNeuralNet.trainingAlgorithms.INetTrainingAlgorithm}
        // Lernverfahren {@link mscJNeuralNet.trainingAlgorithms.INetTrainingAlgorithm} mit Netz verbinden.
        
        lNetTrainAlgo.setNet(myNet);
    	
    		
        try{
            
            // 50 TRAININGSZYKLEN
            
            while (lNetTrainAlgo.getCycle()<50){
              Net.train(lTrippleXORtrainInput, lTrippleXORtrainOutput, lNetTrainAlgo);
            }
    
            
            // {@link mscJNeuralNet.netPerformanceStatistics.NetPerformanceStatisticsCalculator}
            // {@link mscJNeuralNet.netPerformanceStatistics.NetPerformanceStatistics}
            // Berechnen der aktuellen Netzperformanz (Soll-Ist Fehler)
            
            NetPerformanceStatistics lNetPerformance = 
              NetPerformanceStatisticsCalculator.calculateErrors(
                myNet, lTrippleXORtrainInput, lTrippleXORtrainOutput);
    	
            
            // {@link mscJNeuralNet.netPerformanceStatistics.NetPerformanceReporter}
            // Formatierte Ausgabe der Netzperformanz
            
            NetPerformanceReporter.getNetPerformance(
              lNetPerformance, lNetTrainAlgo.getCycle());
        }
        catch({@link mscJNeuralNet.net.PatternDoesNotMatchNetException} e){
            
            // Wird aufgerufen, wenn die Lerndatensätze mehr Eingabe-/Ausgabewerte 
            // enthalten als Eingabe-/Ausgabeneuronen im MLP vorhanden sind.
            
            e.printStackTrace();
        }
      }	
    }
    

    Für eine anspruchsvollere Verwaltung des Lernvorgangs steht die Klasse {@link mscJNeuralNet.trainer.NetTrainer} zur Verfügung, die u.a. trainieren mehrerer Zyklen als nebenläufigen Prozess oder trainieren der Lerndaten in zufälliger Reihenfolge unterstützt.

    @author M. Serhat Cinar